home *** CD-ROM | disk | FTP | other *** search
- /*
- * BLOCK.C
- *
- * main interrupt routine
- */
-
- #include <dos.h>
- #include "block.h"
-
- /*
- * normalize()
- *
- * normalize() guarantees that the offset portion of a far
- * pointer is as small as possible. A complete 20-bit address on
- * the processor can be calculated as
- *
- * (segment * 16) + offset
- *
- * thus, the offset can be kept to a value between 0 and 15. I
- * use the FP_SEG and FP_OFF macro's in Microsoft's dos.h to
- * manipulate the segment and offset of the far pointer. If your
- * compiler doesn't support such a facility, see the _rawscroll
- * routine in RAW.ASM, where I do it in assembly language.
- *
- * The whole point of this is to allow a lot of pointer
- * incrementing, using just the offset, without worrying about
- * wrapping around.
- */
-
- static void normalize(p)
- int far **p;
- {
- offset = FP_OFF(*p);
- FP_SEG(*p) = FP_SEG(*p) + (offset >> 4);
- FP_OFF(*p) = offset & 017;
- }
-
-
- /*
- * interrupt()
- *
- * interrupt() takes care of the commands as they come in from
- * the request header. Because of the size of the RAM disk
- * buffer, the driver initialization could not be appended to the
- * back of the driver, and is in-line like everything else.
- */
-
- void interrupt()
- {
- command = rh->command;
- start = rh->b18.io.start;
- count = rh->b18.io.count;
- transfer = (int far *) rh->b14.transfer;
- switch (command)
- {
- case 0: /* driver initialization */
- source = ram_disk;
- FP_SEG(source) = FP_SEG(source) + 0x1000;
- normalize(&source);
- rh->b14.transfer= (char far *) source;
- rh->b18.bpb = bpb_tab;
- rh->data = 1;
- rh->status = DONE;
- break;
- case 1: /* media check */
- rh->b14.media_change_code = 1; /* disk has
- * not been changed */
- rh->status = DONE;
- break;
- case 2: /* build parameter block */
- rh->b18.bpb = &bpb;
- break;
- case 4: /* read */
- case 8: /* write */
- case 9: /* write with verify */
- if (start > MAX_BLK || count > MAX_BLK ||
- start + count > MAX_BLK)
- {
- rh->status = BLK_NOT_FOUND | ERROR;
- break;
- }
- if (command == 4)
- {
- source = ram_disk;
- normalize(&source);
- source += (BLK_SIZE / sizeof(int)) * start;
- dest = transfer;
- }
- else
- {
- source = transfer;
- dest = ram_disk;
- normalize(&dest);
- dest += (BLK_SIZE / sizeof(int)) * start;
- }
- normalize(&dest);
- normalize(&source);
- for (k1 = 0; k1 < count; k1++)
- for (k2 = 0; k2 < BLK_SIZE / sizeof(int); k2++)
- *dest++ = *source++;
- rh->status = DONE;
- break;
- case 15: /* removable media check */
- rh->status = DONE | BUSY;
- break;
- case 5: /* non-destructive read */
- case 6: /* input status */
- case 7: /* flush input buffers */
- case 10: /* output status */
- case 11: /* flush output buffers */
- case 13: /* device open */
- case 14: /* device done */
- rh->status = DONE;
- break;
- case 3: /* ioctl read */
- case 12: /* ioctl write */
- default:
- rh->status = UNKNOWN_COMMAND | ERROR | DONE;
- break;
- }
- }
-
-